//////////////////////////////////////////////////////////////////////////////////////////////////////
// 项目名   : SafeSingleton
// 文件名   : SingletonPattern.h
// 作者     : Aiye
// 日期     : 2025/9/22 21:00
// 邮箱     : 2878548868@qq.com
// 摘要     : 线程安全的单例模式详解
//////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef SAFESINGLETON_SINGLETONPATTERN_H
#define SAFESINGLETON_SINGLETONPATTERN_H
#include <iostream>
#include <bits/this_thread_sleep.h>

/**
 * @brief 线程不安全的懒汉模式
 */
class SingletonLazyUnsafe
{
public:
    static SingletonLazyUnsafe* getInstance()
    {
        if (s_pInstance == nullptr)
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 等待一会
            s_pInstance = new SingletonLazyUnsafe(); // 后写入者覆盖地址
        }
        return s_pInstance;
    }

    void print() const
    {
        std::cout << "Singleton-lazyMode address:"  << s_pInstance << std::endl;
    }

    SingletonLazyUnsafe(const SingletonLazyUnsafe& other) = delete;
    SingletonLazyUnsafe& operator=(const SingletonLazyUnsafe& other) = delete;
private:
    SingletonLazyUnsafe()
    {
        s_nConstructCount.fetch_add(1);
    }

    ~SingletonLazyUnsafe() = default;
public:
    static std::atomic<int> s_nConstructCount; // 统计构造次数
private:
    static SingletonLazyUnsafe* s_pInstance;
};

SingletonLazyUnsafe* SingletonLazyUnsafe::s_pInstance{nullptr};
std::atomic<int> SingletonLazyUnsafe::s_nConstructCount{0};

/**
 * @brief 采用双重锁模式
 */
class SingletonLazyDCLP
{
public:
    static SingletonLazyDCLP* getInstance()
    {
        if (s_pInstance == nullptr)
        { // 第一次检查
            std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 等待一会
            std::lock_guard lock{s_mutex};

            if (s_pInstance == nullptr)
            {
                s_pInstance = new SingletonLazyDCLP();
            }
        }
        return s_pInstance;
    }

    SingletonLazyDCLP(const SingletonLazyDCLP& other) = delete;
    SingletonLazyDCLP& operator=(const SingletonLazyDCLP& other) = delete;
private:
    SingletonLazyDCLP()
    {
        s_nConstructCount.fetch_add(1);
    }

    ~SingletonLazyDCLP() = default;
public:
    static std::atomic<int> s_nConstructCount; // 统计构造次数
private:
    static SingletonLazyDCLP* s_pInstance;
    static std::mutex s_mutex;
};

/**
 * @brief 线程安全且简单的单例模式
 */
class Singleton
{
public:
    /**
     * @brief 由编译器控制只会创建一个
     * @return 静态变量只会初始化一次
     */
    static Singleton& getInstance()
    {
        static Singleton _instance;
        return _instance;
    }

    Singleton(const Singleton& other) = delete;
    Singleton& operator=(const Singleton& other) = delete;
private:
    Singleton() = default;
    ~Singleton() = default;
};

#endif //SAFESINGLETON_SINGLETONPATTERN_H